package plgdb

import (
	"dgo/MyProj/PrjDBUtils"
	"fmt"
	"gitee.com/ymofen/gobase/golog"
	"gitee.com/ymofen/supervalue"
	"strings"
)

/**
  "$exec":{    // 执行语句: $name$为 name参数的占位符
      "__tracesql":1,    // 响应时返回sql
     "sql":"update goods set status=$status$ where fname='$name$' and status=0"
  },
*/

func (this *PlgDBBase) innerGetDBResSQL(conf *wrapper.SuperValue, args *wrapper.SuperValue, drivername string) string {
	if conf == nil {
		return ""
	}
	var sql string
	if conf.IsObject() {
		if len(drivername) > 0 {
			sql = conf.StringByName(fmt.Sprintf("sql-%s", drivername), "")
		}
		if len(sql) == 0 {
			sql = conf.StringByName("sql", "")
		}
	} else {
		sql = conf.String()
	}

	if args != nil && args.Count() > 0 {
		args.Range(func(key string, val *wrapper.SuperValue) bool {
			id := key
			if len(id) == 0 {
				id = val.StringByName("id", "")
				if len(id) > 0 {
					id = fmt.Sprintf("$%s$", id)
					sql = strings.ReplaceAll(sql, id, val.StringByName("val", ""))
				}
			} else {
				id = fmt.Sprintf("$%s$", id)
				if val.IsObject() {
					sql = strings.ReplaceAll(sql, id, val.StringByName("val", ""))
				} else {
					sql = strings.ReplaceAll(sql, id, val.String())
				}
			}
			return true
		})
		return sql
	}

	return sql

}

func (this *PlgDBBase) DBResExec(param *PlgDBExecParam) (errcode int, err error) {

	dbres := param.DBResConf
	if dbres == nil {
		dbres = this.GetDBResConf(param.ResID)
		param.DBResConf = dbres
	}
	dbres = param.HttpReq.DoResConfig(dbres)

	if dbres == nil {
		errcode = ERR_IN_PARAM_INVALID
		err = fmt.Errorf("找不到对应的资源[%s]", param.ResID)
		return
	}

	if len(param.DataSourceid) == 0 {
		param.DataSourceid = this.Default_datasourceid
	}

	dbname := param.DBName
	var dao *PrjDBUtils.DAOHelper
	if len(dbname) > 0 {
		dao = PrjDBUtils.NewDAOHelperEx(param.DataSourceid, dbname)
	} else {
		dao = PrjDBUtils.NewDAOHelper(param.DataSourceid)
	}
	err = dao.PrepareDBConn()
	if err != nil {
		errcode = ERR_DB_ERR
		return
	}
	param.Dao = dao

	resStep := param.ReqStringByName("__resstep", "")
	if len(resStep) == 0 {
		resStep = "$exec"
	}

	operaConf := dbres.ValueByName(fmt.Sprintf("%s-%s", resStep, dao.DriverName))
	if operaConf == nil {
		operaConf = dbres.ValueByName(resStep)

		if operaConf == nil {
			return ERR_INNER, fmt.Errorf("配置非法[%s],找不到对应的[%s]配置", param.ResID, resStep)
		}
	}

	//operaConf := dbres.ValueByName(resStep)
	//if operaConf == nil {
	//	return ERR_INNER, fmt.Errorf("配置非法[%s],找不到对应的[$sel]配置", resStep)
	//}

	checkconf := operaConf.ValueByName("check")
	if checkconf == nil {
		checkconf = dbres.ValueByName("check")
	}

	if ok, itm := this.checkVarByResConf(checkconf, param.GetParamVal); !ok {
		errcode = ERR_IN_PARAM_INVALID
		code := itm.IntByName("errcode", 0)
		msg := itm.StringByName("msg", "")
		if code != 0 {
			errcode = code
		}
		err = fmt.Errorf(msg)
		return
	}

	dbres.CheckStrFunc("__datasource", func(strv string) {
		param.DataSourceid = strv
	})

	param.trans = operaConf.BoolByName("trans", false)
	param.tracesql = operaConf.IntByName("__tracesql", 0)

	if param.trans {
		dao.DBConn.BeginTrans()
		defer dao.DBConn.AutoDoneTrans()
	}

	sql := this.innerGetDBResSQL(operaConf, param.Args, dao.DriverName)

	this.checkProcessVar(&sql, param.GetParamVal)

	n, errsql, e1 := dao.ExecuteBatchSQL(sql)
	if e1 != nil {
		golog.Warnf("sql:%s, err:%s", errsql, e1.Error())
		if param.tracesql == 1 {
			param.Resp.SetKeyValues("errsql", errsql)
		}
		return ERR_DB_ERR, e1
	}
	if param.tracesql == 1 {
		param.Resp.SetKeyValue("tracesql", sql)
	}
	param.Resp.SetKeyValue("upcnt", n)
	param.Resp.SetKeyValue("code", 0)
	return
}
